class IndexedDBManager {
  private dbName: string;
  private storeName: string;
  private db: IDBDatabase | null;

  constructor(dbName: string, storeName: string) {
    this.dbName = dbName;
    this.storeName = storeName;
    this.db = null;
  }

  private ensureDBIsOpen(): Promise<void> {

    return new Promise((resolve, reject) => {
      if (this.db) {
        resolve();
      } else {
        const request = indexedDB.open(this.dbName);
        request.onerror = (event) => {
          // console.error('打开数据库出错:', (event.target as IDBRequest<IDBDatabase>).error);
          resolve(); // Return without rejecting to avoid throwing an error
        };

        request.onsuccess = (event) => {
          this.db = (event.target as IDBRequest<IDBDatabase>).result;
          resolve();
        };

        request.onupgradeneeded = (event) => {
          this.db = (event.target as IDBOpenDBRequest).result as IDBDatabase;
          if (!this.db.objectStoreNames.contains(this.storeName)) {
            this.db.createObjectStore(this.storeName, { keyPath: 'id', autoIncrement: true });

          }
        };
      }
    });
  }

  public async addObject(data: any): Promise<boolean> {
    await this.ensureDBIsOpen();
    const transaction = this.db?.transaction([this.storeName], 'readwrite');
    const objectStore = transaction?.objectStore(this.storeName);

    if (objectStore) {
      console.log(data)
      const request = objectStore.add(data);
      return new Promise((resolve) => {
        request.onsuccess = () => {
          resolve(true);
        };
        request.onerror = () => {
          resolve(false);
        };
      });
    } else {

      return false;
    }
  }

  public async getObject(id: number): Promise<any | undefined> {
    await this.ensureDBIsOpen();
    const transaction = this.db?.transaction([this.storeName], 'readonly');
    const objectStore = transaction?.objectStore(this.storeName);

    if (objectStore) {
      const request = objectStore.get(id);

      return new Promise((resolve) => {
        request.onsuccess = (event) => {
          const data = (event.target as IDBRequest).result;
          if (data) {

            resolve(data);
          } else {

            resolve(undefined);
          }
        };

        request.onerror = () => {

          resolve(undefined);
        };
      });
    } else {

      return undefined;
    }
  }

  public async getAllObjects(): Promise<any[]> {
    await this.ensureDBIsOpen();
    const transaction = this.db?.transaction([this.storeName], 'readonly');
    const objectStore = transaction?.objectStore(this.storeName);

    if (objectStore) {
      const request = objectStore.getAll();

      return new Promise((resolve) => {
        request.onsuccess = (event) => {
          const data = (event.target as IDBRequest).result;

          resolve(data);
        };

        request.onerror = () => {

          resolve([]);
        };
      });
    } else {

      return [];
    }
  }

  public async updateObject(data: any): Promise<boolean> {
    await this.ensureDBIsOpen();
    const transaction = this.db?.transaction([this.storeName], 'readwrite');
    const objectStore = transaction?.objectStore(this.storeName);

    if (objectStore) {
      const request = objectStore.put(data);

      return new Promise((resolve) => {
        request.onsuccess = () => {

          resolve(true);
        };

        request.onerror = () => {

          resolve(false);
        };
      });
    } else {

      return false;
    }
  }

  public async deleteObject(id: number): Promise<boolean> {
    await this.ensureDBIsOpen();
    const transaction = this.db?.transaction([this.storeName], 'readwrite');
    const objectStore = transaction?.objectStore(this.storeName);

    if (objectStore) {
      const request = objectStore.delete(id);

      return new Promise((resolve) => {
        request.onsuccess = () => {

          resolve(true);
        };

        request.onerror = () => {
          resolve(false);
        };
      });
    } else {

      return false;
    }
  }
}

export default IndexedDBManager;